#include "String.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

String_Ptr Init_String(size_t init_len)
{
    String *str_ptr = (String*) malloc(sizeof(String));
    if (str_ptr == NULL)
        return NULL;
    str_ptr->start = str_ptr->end = (char*) calloc(sizeof(char), init_len);
    if (!str_ptr->start)
        return NULL;
    str_ptr->len = init_len;
    return str_ptr;
}

void Append_Chars(String_Ptr str, const char *chars, size_t n)
{
    if (n <= 0)
        return;
    // 多减1是为了存放'\0'
    int remains = str->len - (str->end - str->start) - 1;
    if (remains < n) {
        // 扩容
        size_t half_len = str->len / 2;
        size_t new_len = half_len > n ? str->len + half_len : n + half_len;
        char *new_start = (char*) realloc(str->start, sizeof(char) * new_len);
        if (!new_start)
            exit(-1);
        str->start = new_start;
        str->end = str->start + str->len;
        str->len = new_len;
    }
    memcpy(str->end, chars, n);
    str->end += n;
    *str->end = '\0';
}

void Destroy_String(String_Ptr str)
{
    free(str->start);
    free(str);
}

void test_String() {
    String_Ptr str = Init_String(16);
    char ch[16] = {'h', 'e', 'l', 'l', 'o'};
    Append_Chars(str, ch, 5);
    printf("str=%s\n", str->start);

    ch[0] = ' ';
    ch[1] = 'w';
    ch[2] = 'o';
    ch[3] = 'r';
    ch[4] = 'l';
    ch[5] = 'd';
    Append_Chars(str, ch, 6);
    printf("str=%s\n", str->start);
    Destroy_String(str);
}